//
//  MapsView.m
//  apple_maps
//
//  Created by os on 3/7/25.
//

#import "MapsView.h"
#import <MapKit/MapKit.h>

@interface MapsView ()<FlutterStreamHandler,CLLocationManagerDelegate, MKMapViewDelegate>

@property (nonatomic,copy) NSDictionary *args;
@property (nonatomic,assign) NSInteger viewId;

@property (nonatomic,strong) FlutterMethodChannel *channel;
@property (nonatomic,strong) FlutterEventSink sink;

@property (strong, nonatomic) MKMapView *mapView;
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (nonatomic, strong) MKAnnotationView *userLocationAnnotationView;

@property (nonatomic,copy) NSString *annotationIcon;
@property (nonatomic,copy) NSString *annotationIconSize;
@property (nonatomic,copy) NSString *regionDistance;

@property (nonatomic,strong) CLGeocoder *gcode;
@property (nonatomic,strong) CLLocation *previousLocation;

@end


@implementation MapsView


- (instancetype)initWithFrame:(CGRect)frame viewIdentifier:(int64_t)viewId arguments:(id _Nullable)args registrar:(NSObject<FlutterPluginRegistrar>*)registrar
{
    self = [super init];
    if (self) {
        //初始值
        self.args = args;
        self.viewId = viewId;
        
        self.annotationIcon = args[@"annotationIcon"];
        self.annotationIconSize = args[@"annotationIconSize"];
        self.regionDistance = args[@"regionDistance"];
        
        //处理flutter传过来的消息
        NSString* channelName = [NSString stringWithFormat:@"apple_maps_view_%lld", viewId];
        self.channel = [FlutterMethodChannel methodChannelWithName:channelName binaryMessenger:registrar.messenger];
        __weak __typeof__(self) weakSelf = self;
        [self.channel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult  _Nonnull result) {
            [weakSelf onMethodCall:call result:result];
        }];
        
        //主动给flutter发消息
        FlutterEventChannel * event = [FlutterEventChannel eventChannelWithName:[NSString stringWithFormat:@"apple_maps_sink_view_%lld",viewId] binaryMessenger:registrar.messenger];
        [event setStreamHandler:self];
        
        
        // 初始化地图视图
        self.mapView = [[MKMapView alloc] init];
        self.mapView.delegate = self;
        self.mapView.showsUserLocation = YES; // 显示用户位置
        self.mapView.userTrackingMode = MKUserTrackingModeFollowWithHeading;
        self.mapView.showsCompass = NO; // 不显示指南针
        
        // 当手机旋转时，地图不旋转 // 强制地图恢复到默认方向
//        self.mapView.rotateEnabled = NO;
//        MKMapCamera *camera = [self.mapView.camera copy];
//        camera.heading = 0; // 设置地图方向为正北
//        self.mapView.camera = camera;
        
        [self addSubview:self.mapView];
        
        // 初始化位置管理器
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; // 定位精确度
        self.locationManager.distanceFilter = 20; // 每隔5米定位一次
        self.locationManager.headingFilter = 10; // 朝向改变时，每隔多少度调用一次
        
//        UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
//        [img setImage:[UIImage imageNamed:@"mapheader"]];
//        [self addSubview:img];
        
    }
    return self;
}


//点击事件
- (void)click{
    self.sink(@{@"type":@"1"});
}

//[event setStreamHandler:instance]; FlutterStreamHandler代理方法，用于获取FlutterEventSink sink
- (FlutterError* _Nullable)onListenWithArguments:(id _Nullable)arguments
                                       eventSink:(FlutterEventSink)events{
    
    self.sink = events;
    return nil;
}
- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments{
    return nil;
}

- (void)layoutSubviews{
    [super layoutSubviews];
    
    // 设置尺寸
    self.mapView.frame = self.bounds;
    
}

//处理flutter传过来的消息
-(void)onMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result{
    NSString *method = [call method];
    if ([method isEqualToString:@"updateText"]) {
        //获取参数
        NSDictionary *dict = call.arguments;
        NSString *content = dict[@"updateText"];
        if (content!=nil) {
            
        }
    }else if ([method isEqualToString:@"startUpdatingLocation"]) {
        // 开始更新位置
        NSLog(@"startUpdatingLocation...");
        [self.locationManager startUpdatingLocation];
    }else if ([method isEqualToString:@"auth"]) {
        // 开始更新位置
        NSLog(@"auth...");
        [self.locationManager requestWhenInUseAuthorization];
    }else if ([method isEqualToString:@"stopUpdatingLocation"]) {
        // 开始更新位置
        NSLog(@"stopUpdatingLocation...");
        [self.locationManager stopUpdatingLocation];
    }else if ([method isEqualToString:@"locationServicesEnabled"]) {
        // 位置服务是否可用
        NSLog(@"locationServicesEnabled...");
        BOOL canUse = [CLLocationManager locationServicesEnabled];
        result(canUse ? @"1": @"0");
    }else if ([method isEqualToString:@"startUpdatingHeading"]) {
        // 开始监听设备朝向
        NSLog(@"startUpdatingHeading...");
        [self.locationManager startUpdatingHeading];
    }else if ([method isEqualToString:@"stopUpdatingHeading"]) {
        // 结束监听设备朝向
        NSLog(@"stopUpdatingHeading...");
        [self.locationManager stopUpdatingHeading];
    }
    else{
        //其他方法事件
    }
}

#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
    CLLocation *location = [locations lastObject];
    if (location) {
        
        if (!self.gcode) {
            self.gcode = [[CLGeocoder alloc] init];
        }
        
        
        // 确保不频繁反编码
        CLLocationDistance distance = [self.previousLocation distanceFromLocation:location];
        if (self.previousLocation == nil || distance > 20) {
            self.previousLocation = location;
            [self.gcode reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
                if (error) {
                    NSLog(@"Geocode failed with error 这儿有错误: %@", error);
                    return;
                }
                
                if (placemarks.count > 0) {
                    CLPlacemark *placemark = [placemarks firstObject];
                    if (placemark) {
                        CLLocationCoordinate2D center = placemark.location.coordinate;
                        
                        CGFloat distance = [self.regionDistance doubleValue];
                        MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(center, distance, distance); // 多少米的范围
                        [self.mapView setRegion:region animated:NO];
                    }
                    
                }
            }];
        }
        
    }
}

- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
    // 获取设备朝向（磁北方向）
    CGFloat heading = newHeading.magneticHeading;
    
    // 旋转用户位置图片
    if (self.userLocationAnnotationView) {
        [UIView animateWithDuration:0.3 animations:^{
            self.userLocationAnnotationView.transform = CGAffineTransformMakeRotation((CGFloat)(heading * M_PI / 180));
        }];
    }
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"定位失败: %@", error);
    
}


#pragma mark - MKMapViewDelegate

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        // 创建自定义的AnnotationView
        static NSString *identifier = @"CustomUserLocationAnnotationView";
        MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (!annotationView) {
            annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        }
        
        // 设置自定义图片
        annotationView.image = [UIImage imageNamed:self.annotationIcon];
        // 设置大小
        CGFloat size = [self.annotationIconSize floatValue];
        annotationView.bounds = CGRectMake(0, 0, size, size);
        self.userLocationAnnotationView = annotationView;
        return annotationView;
    }
    return nil;
}

@end
